// <editor-fold defaultstate="collapsed" desc="GNU GPLv3 header">
/*
 * File:   main.c
 *
 * Copyright (C) 2013 Robert Antoni Buj Gelonch <rbuj@uoc.edu>
 * Copyright (C) 2013 David Megias Jimenez <dmegias@uoc.edu>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="defines">
#ifndef FCY
#define FCY 40000000UL // 40 MIPS
#endif
#define UxBRG_VALUE 0
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="includes">
#include <stdio.h>
#include <stdlib.h>
#include <p33FJ256GP710A.h>
#include <libpic30.h>
#include "../include/LCD_TM162JCAWG1.h"
#include <uart.h>
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="osc config">
/*
 * Fosc = Fin x (M / (N1 x N2))
 * Fcy = MIPS = Fosc / 2
 *
 * XTAL Explorer 16 = 8 MHz
 *
 * Fosc = 8 MHz x (40 / (2x2) = 80 MHz
 * Fcy = MIPS = 80 MHz / 2 = 39613750 IPS = 40 MIPS
 *
 */
/* Primary Oscillator (POSC) on the OSC1 and OSC2 pins 8 MHz */
_FOSCSEL(FNOSC_PRIPLL);

/* Enable clock switcing and configure */
_FOSC(FCKSM_CSDCMD & OSCIOFNC_OFF & POSCMD_XT);

/* Watchdog Timer: OFF */
_FWDT(FWDTEN_OFF);
// </editor-fold>

int main(int argc, char** argv) {
    /* Holds the value of baud register   */
    unsigned int baudvalue;
    /* Holds the value of uart config reg */
    unsigned int U2MODEvalue;
    /* Holds the information regarding uart TX & RX interrupt modes */
    unsigned int U2STAvalue;

    const char mytext[] = "Press S3 to cont";

    // <editor-fold defaultstate="collapsed" desc="LEDs OFF">
    /* set LEDs (D3-D10/RA0-RA7) drive state low */
    LATA = 0xFF00;
    /* set LED pins (D3-D10/RA0-RA7) as outputs */
    TRISA = 0xFF00;
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="40 MIPS 8 MHz XTAL">
    // Configure PLL prescaller, PLL postscaller. PLL divisor
    PLLFBD = 38; // M = 40
    CLKDIVbits.PLLPOST = 0; // N2=2
    CLKDIVbits.PLLPRE = 0; // N1=2

    // Initiate Clock Switch to Primary Oscillator with PLL (NOSC = 0b011)
    __builtin_write_OSCCONH(0x03);
    __builtin_write_OSCCONL(0x01);

    // Wait for Clock switch to occur
    while (OSCCONbits.COSC != 0b011);

    // Wait for PLL to lock
    while (OSCCONbits.LOCK != 1) {
    };
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="LCD: Press S3 to cont">
    lcd_init();
    lcd_puts((unsigned char*) &mytext[0], sizeof (mytext) - 1);
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="UART 230.4kbps">
    /* Turn off UART1module */
    CloseUART2();
    __C30_UART = 2;

    /***************************************************************************
     * RS232 38.4kbps 8N1
     ***************************************************************************
     *      U2BRG = 0x40; (40000000/16*38400) - 1
     *      U2MODEbits.UARTEN = 1;
     ***************************************************************************/
    // U2MODEvalue = UART_EN & 0x8FFF & 0xF0FF & UART_DIS_WAKE & UART_DIS_LOOPBACK &
    //        UART_DIS_ABAUD & UART_UXRX_IDLE_ONE & UART_BRGH_SIXTEEN &
    //        UART_NO_PAR_8BIT & UART_1STOPBIT;
    // baudvalue = 0x0040;

    /***************************************************************************
     * RS232 57.6kbps 8N1
     ***************************************************************************
     *      U2BRG = 0x40; (40000000/16*57600) - 1
     *      U2MODEbits.UARTEN = 1;
     ***************************************************************************/
    // U2MODEvalue = UART_EN & 0x8FFF & 0xF0FF & UART_DIS_WAKE & UART_DIS_LOOPBACK &
    //        UART_DIS_ABAUD & UART_UXRX_IDLE_ONE & UART_BRGH_SIXTEEN &
    //        UART_NO_PAR_8BIT & UART_1STOPBIT;
    // baudvalue = 0x002A;

    /***************************************************************************
     * RS232 115.2kbps 8N1
     ***************************************************************************
     *      U2BRG = 0x40; (40000000/16*115200) - 1
     *      U2MODEbits.UARTEN = 1;
     ***************************************************************************/
    // U2MODEvalue = UART_EN & 0x8FFF & 0xF0FF & UART_DIS_WAKE & UART_DIS_LOOPBACK &
    //       UART_DIS_ABAUD & UART_UXRX_IDLE_ONE & UART_BRGH_SIXTEEN &
    //       UART_NO_PAR_8BIT & UART_1STOPBIT;
    // baudvalue = 0x0015;

    /***************************************************************************
     * RS232 230.4kbps 8N1
     ***************************************************************************
     *      U2BRG = 0x40; (40000000/16*230400) - 1
     *      U2MODEbits.UARTEN = 1;
     ***************************************************************************/
    U2MODEvalue = UART_EN & 0x8FFF & 0xF0FF & UART_DIS_WAKE & UART_DIS_LOOPBACK &
            UART_DIS_ABAUD & UART_UXRX_IDLE_ONE & UART_BRGH_SIXTEEN &
            UART_NO_PAR_8BIT & UART_1STOPBIT;
    baudvalue = 0x000A;

    U2STAvalue = 0;

    OpenUART2(U2MODEvalue, U2STAvalue, baudvalue);
    // </editor-fold>

    while (1) {
        /* wait here until switch S3 is pressed */
        while (PORTDbits.RD6);

        printf("Hello world %d", U2BRG);
        WriteUART2(10);
        WriteUART2(13);
        while (BusyUART2());
        
        __delay32(FCY);
    }
    return (EXIT_SUCCESS);
}